home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / sega.c < prev    next >
C/C++ Source or Header  |  1998-08-20  |  7KB  |  256 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Generic functions used by the Sega Vector games
  6.  
  7. ***************************************************************************/
  8.  
  9. /*
  10.  * History:
  11.  *
  12.  * 97???? Converted Al Kossow's G80 sources. LBO
  13.  * 970807 Scaling support and dynamic sin/cos tables. ASG
  14.  * 980124 Suport for antialiasing. .ac
  15.  * 980203 cleaned up and interfaced to generic vector routines. BW
  16.  *
  17.  * TODO: use floating point math instead of fixed point.
  18.  */
  19.  
  20. #include "driver.h"
  21. #include "avgdvg.h"
  22. #include "vector.h"
  23. #include <math.h>
  24.  
  25. #define VEC_SHIFT 15    /* do not use a higher value. Values will overflow */
  26.  
  27. static int width, height, cent_x, cent_y, min_x, min_y, max_x, max_y;
  28. static long *sinTable, *cosTable;
  29. static int intensity;
  30.  
  31. void sega_generate_vector_list (void)
  32. {
  33.     int deltax, deltay;
  34.     int currentX, currentY;
  35.  
  36.     int vectorIndex;
  37.     int symbolIndex;
  38.  
  39.     int rotate, scale;
  40.     int attrib;
  41.  
  42.     int angle, length;
  43.     int color;
  44.  
  45.     int draw;
  46.  
  47.     vector_clear_list();
  48.  
  49.     symbolIndex = 0;    /* Reset vector PC to 0 */
  50.  
  51.     /*
  52.      * walk the symbol list until 'last symbol' set
  53.      */
  54.  
  55.     do {
  56.         draw = vectorram[symbolIndex++];
  57.  
  58.         if (draw & 1)    /* if symbol active */
  59.         {
  60.             currentX    = vectorram[symbolIndex + 0] | (vectorram[symbolIndex + 1] << 8);
  61.             currentY    = vectorram[symbolIndex + 2] | (vectorram[symbolIndex + 3] << 8);
  62.             vectorIndex = vectorram[symbolIndex + 4] | (vectorram[symbolIndex + 5] << 8);
  63.             rotate      = vectorram[symbolIndex + 6] | (vectorram[symbolIndex + 7] << 8);
  64.             scale       = vectorram[symbolIndex + 8];
  65.  
  66.             currentX = ((currentX & 0x7ff) - min_x) << VEC_SHIFT;
  67.             currentY = (max_y - (currentY & 0x7ff)) << VEC_SHIFT;
  68.             vector_add_point ( currentX, currentY, 0, 0);
  69.             vectorIndex &= 0xfff;
  70.  
  71.             /* walk the vector list until 'last vector' bit */
  72.             /* is set in attributes */
  73.  
  74.             do
  75.             {
  76.                 attrib = vectorram[vectorIndex + 0];
  77.                 length = vectorram[vectorIndex + 1];
  78.                 angle  = vectorram[vectorIndex + 2] | (vectorram[vectorIndex + 3] << 8);
  79.  
  80.                 vectorIndex += 4;
  81.  
  82.                 /* calculate deltas based on len, angle(s), and scale factor */
  83.  
  84.                 angle = (angle + rotate) & 0x3ff;
  85.                 deltax = sinTable[angle] * scale * length;
  86.                 deltay = cosTable[angle] * scale * length;
  87.  
  88.                 currentX += deltax >> 7;
  89.                 currentY -= deltay >> 7;
  90.  
  91.                 color = attrib & 0x7e;
  92.                 if ((attrib & 1) && color)
  93.                 {
  94.                     if (translucency)
  95.                         intensity = 0xa0; /* leave room for translucency */
  96.                     else
  97.                         intensity = 0xff;
  98.                 }
  99.                 else
  100.                     intensity = 0;
  101.                 vector_add_point ( currentX, currentY, color, intensity );
  102.  
  103.             } while (!(attrib & 0x80));
  104.         }
  105.  
  106.         symbolIndex += 9;
  107.         if (symbolIndex >= vectorram_size)
  108.             break;
  109.  
  110.     } while (!(draw & 0x80));
  111. }
  112. /***************************************************************************
  113.  
  114.   The Sega vector games don't have a color PROM, it uses RGB values for the
  115.   vector guns.
  116.   This routine sets up the color tables to simulate it.
  117.  
  118. ***************************************************************************/
  119.  
  120.  
  121. void sega_init_colors (unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  122. {
  123.     int i,r,g,b;
  124.  
  125.     /* Bits are-> Red: 6&5 (0x60), Green: 4&3 (0x18), Blue: 2&1 (0x06) */
  126.     for (i=0; i<128; i+=2)
  127.     {
  128.         palette[3*i  ] = 85 * ((i>>5)&0x3);
  129.         palette[3*i+1] = 85 * ((i>>3)&0x3);
  130.         palette[3*i+2] = 85 * ((i>>1)&0x3);
  131.         /* Set the color table */
  132.         colortable[i] = i;
  133.     }
  134.     /*
  135.      * Fill in the holes with good anti-aliasing colors.  This is a very good
  136.      * range of colors based on the previous palette entries.     .ac JAN2498
  137.      */
  138.     i=1;
  139.     for (r=0; r<=6; r++)
  140.     {
  141.         for (g=0; g<=6; g++)
  142.         {
  143.             for (b=0; b<=6; b++)
  144.             {
  145.                 if (!((r|g|b)&0x1) ) continue;
  146.                 if ((g==5 || g==6) && (b==1 || b==2 || r==1 || r==2)) continue;
  147.                 if ((g==3 || g==4) && (b==1         || r==1        )) continue;
  148.                 if ((b==6 || r==6) && (g==1 || g==2                )) continue;
  149.                 if ((r==5)         && (b==1)                        ) continue;
  150.                 if ((b==5)         && (r==1)                        ) continue;
  151.                 palette[3*i  ] = (255*r) / 6;
  152.                 palette[3*i+1] = (255*g) / 6;
  153.                 palette[3*i+2] = (255*b) / 6;
  154.                 colortable[i]  = i;
  155.                 if (i < 128)
  156.                     i+=2;
  157.                 else
  158.                     i++;
  159.             }
  160.         }
  161.     }
  162.     /* There are still 4 colors left, just going to put some grays in. */
  163.     for (i=252; i<=255; i++)
  164.     {
  165.         palette[3*i  ] =
  166.         palette[3*i+1] =
  167.         palette[3*i+2] = 107 + (42*(i-252));
  168.     }
  169. }
  170.  
  171. /***************************************************************************
  172.  
  173.   Start the video hardware emulation.
  174.  
  175. ***************************************************************************/
  176. int sega_vh_start (void)
  177. {
  178.     int i;
  179.  
  180.     if (vectorram_size == 0)
  181.         return 1;
  182.     min_x =Machine->drv->visible_area.min_x;
  183.     min_y =Machine->drv->visible_area.min_y;
  184.     max_x =Machine->drv->visible_area.max_x;
  185.     max_y =Machine->drv->visible_area.max_y;
  186.     width =max_x-min_x;
  187.     height=max_y-min_y;
  188.     cent_x=(max_x+min_x)/2;
  189.     cent_y=(max_y+min_y)/2;
  190.  
  191.     vector_set_shift (VEC_SHIFT);
  192.  
  193.     /* allocate memory for the sine and cosine lookup tables ASG 080697 */
  194.     sinTable = malloc (0x400 * sizeof (long));
  195.     if (!sinTable)
  196.         return 1;
  197.     cosTable = malloc (0x400 * sizeof (long));
  198.     if (!cosTable)
  199.     {
  200.         free (sinTable);
  201.         return 1;
  202.     }
  203.  
  204.     /* generate the sine/cosine lookup tables */
  205.     for (i = 0; i < 0x400; i++)
  206.     {
  207.         double angle = ((2. * PI) / (double)0x400) * (double)i;
  208.         double temp;
  209.  
  210.         temp = sin (angle);
  211.         if (temp < 0)
  212.             sinTable[i] = (long)(temp * (double)(1 << VEC_SHIFT) - 0.5);
  213.         else
  214.             sinTable[i] = (long)(temp * (double)(1 << VEC_SHIFT) + 0.5);
  215.  
  216.         temp = cos (angle);
  217.         if (temp < 0)
  218.             cosTable[i] = (long)(temp * (double)(1 << VEC_SHIFT) - 0.5);
  219.         else
  220.             cosTable[i] = (long)(temp * (double)(1 << VEC_SHIFT) + 0.5);
  221.  
  222.     }
  223.  
  224.     return vector_vh_start();
  225. }
  226.  
  227. /***************************************************************************
  228.  
  229.   Stop the video hardware emulation.
  230.  
  231. ***************************************************************************/
  232. void sega_vh_stop (void)
  233. {
  234.     if (sinTable)
  235.         free (sinTable);
  236.     sinTable = NULL;
  237.     if (cosTable)
  238.         free (cosTable);
  239.     cosTable = NULL;
  240.  
  241.     vector_vh_stop();
  242. }
  243.  
  244. /***************************************************************************
  245.  
  246.   Draw the game screen in the given osd_bitmap.
  247.   Do NOT call osd_update_display() from this function, it will be called by
  248.   the main emulation engine.
  249.  
  250. ***************************************************************************/
  251. void sega_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  252. {
  253.     sega_generate_vector_list();
  254.     vector_vh_update(bitmap,full_refresh);
  255. }
  256.